<template>
    <svg ref="svgContainer" :viewBox="`0 0 ${siblingSpacing * (maxRowLength)} ${levelSpacing * (study_map.length)}`"
        preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" style="width: 100%;">
        <g :transform="`translate(${siblingSpacing * ((maxRowLength + 1) / 2.0)}, ${nodeHeight / 2 + 5})`">
            <g v-for="(node, index) in flattenedNodes" :key="index" @click="handelItemClick(node.key)">
                <!-- 节点矩形 -->
                <rect :x="node.x - nodeWidth / 2" :y="node.y - nodeHeight / 2" :width="nodeWidth" :height="nodeHeight"
                    fill="#f0f0f0" :stroke="(key_of_focused_node == node.key ? '#66ccff' : '#ccc')" rx="5"
                    :stroke-width="(key_of_focused_node == node.key ? 3 : 1)" />
                <!-- 节点标题 -->
                <text :x="node.x" :y="node.y" text-anchor="middle" font-size="16" fill="#333">
                    {{ node.title }}
                </text>
                <!-- 节点描述 -->
                <text :x="node.x" :y="node.y + 20" text-anchor="middle" font-size="12" fill="#666">
                    {{ node.description }}
                </text>
            </g>
            <!-- 贝塞尔连线 -->
            <path v-for="(link, index) in links" :key="'link-' + index" :d="getBezierPath(link)" fill="none"
                stroke="#666" stroke-width="1" />
        </g>
    </svg>
    <NCard :title="focused_node.title">
        {{ focused_node.detail }}
        <template #action>
            <NSpace>
                <NButton type="primary">{{ `切换至“${focused_node.title}”进行学习` }}</NButton>
            </NSpace>
        </template>
    </NCard>

</template>

<script setup lang="ts">
import { ref, onMounted, computed } from "vue";
import { NCard, NButton, NSpace } from "naive-ui";

const svgContainer = ref(null);

const study_map = [
    [
        {
            title: "编程基础",
            key: "programming_skills",
            description: "学习c++, java等",
            detail: "学习编程语言的基础知识，为后续的学习打下基础。这个阶段可以学习c++, java等编程语言，也可以学习一些编程基础的知识，比如数据结构、算法等。",
            father: null,
        },
    ],
    [
        {
            title: "计算机科学基础",
            key: "computer_science",
            description: "专业课",
            father: "programming_skills",
        },
    ],
    [
        {
            title: "研发",
            key: "development",
            description: "开发软件等",
            father: "computer_science",
        },
        {
            title: "科研",
            key: "research",
            description: "研究项目等",
            father: "computer_science",
        },
    ],
    [
        {
            title: "web前端",
            key: "web_frontend",
            description: "用户界面",
            father: "development",
        },
        {
            title: "web后端",
            key: "web_backend",
            description: "用户数据",
            father: "development",
        },
        {
            title: "移动端",
            key: "mobile",
            description: "ios, android",
            father: "development",
        },
        {
            title: "桌面端",
            key: "desktop",
            description: "windows, macos",
            father: "development",
        },
        {
            title: "小程序",
            key: "mini_program",
            description: "微信小程序",
            father: "development",
        },
        {
            title: "人工智能",
            key: "ai",
            description: "深度学习等",
            father: "research",
        },
        {
            title: "交叉学科",
            key: "cross_discipline",
            description: "生物等交叉学科",
            father: "research",
        },
        {
            title: "大数据分析",
            key: "big_data",
            description: "数据分析",
            father: "research",
        },
    ],
];

// 
const key_of_focused_node = ref("");
const focused_node = computed(() => {
    return flattenedNodes.value.find((item: any) => item.key == key_of_focused_node.value) || flattenedNodes.value[0];
});

// 将 study_map 转换为一个带有层级信息的数组
const flattenedNodes = ref([] as any);

function flattenStudyMap(map: any, level = 0, parent: any = null) {
    return map.flatMap((item: any) => {
        return {
            ...item,
            level,
        };
    });
}

// 初始化节点数据
flattenedNodes.value = [];
let currentLevel = 0;
let nodesByLevel = study_map[currentLevel];

while (nodesByLevel && nodesByLevel.length > 0) {
    const nodes: any = flattenStudyMap(nodesByLevel, currentLevel);
    flattenedNodes.value.push(...nodes);
    currentLevel++;
    nodesByLevel = study_map[currentLevel];
}

// 计算每个节点的位置
const nodeWidth = 140; // 每个节点的宽度
const nodeHeight = 60; // 每个节点的高度
const levelSpacing = 100; // 层级之间的间距
const siblingSpacing = 150; // 兄弟节点之间的间距

let maxRowLength = 0;

flattenedNodes.value.forEach((node: any) => {
    // 根据层级计算 Y 坐标
    const y = levelSpacing * node.level;

    // 找到同一层级的兄弟节点
    const siblings: any = flattenedNodes.value.filter(
        (n: any) => n.level === node.level && n.parent === node.parent
    );
    const index = siblings.indexOf(node);

    maxRowLength = Math.max(maxRowLength, siblings.length);

    // 根据兄弟节点的数量和索引计算 X 坐标
    const x =
        (siblingSpacing * (index - (siblings.length) / 2)) + 0;

    node.x = x;
    node.y = y;
});

// 计算连线
const links = computed(() => {
    return flattenedNodes.value.filter((node: any) => { console.log("111"); return node.father }).map((node: any) => {
        const parent = flattenedNodes.value.find((n: any) => n.key === node.father);
        return { source: parent, target: node };
    });
});

// 生成贝塞尔曲线路径
function getBezierPath(link: any) {
    const source = link.source;
    const target = link.target;

    // 控制点
    const controlPointX = (target.x);
    const controlPointY = (source.y + target.y) / 2;

    return `
      M ${source.x} ${source.y + nodeHeight / 2}
      C ${source.x} ${controlPointY}, ${target.x} ${controlPointY}, ${target.x} ${target.y - nodeHeight / 2}
    `;
}

// 点击控制
function handelItemClick(key: string) {
    key_of_focused_node.value = key;
    window.$utils.message.success(key);
}


</script>

<style>
.tree-container {
    width: 100%;
    height: 100vh;
    overflow: auto;
}
</style>